﻿// *************************************************************************************************
// Project: RealSense.Light.Core
// Namespace: RealSense.Light.Core
// File: RealSenseBase.cs  Author: Peter O'Hanlon
// Copyright © Peter O'Hanlon 2014-2015
// Date: 2014/12/29 21:26
// *************************************************************************************************
using RealSense.Light.CodeContracts;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace RealSense.Light.Core
{
  public abstract class RealSenseBase : IDisposable
  {
    private ISenseManager senseManager;

    /// <summary>
    /// Invoke the method and determine whether or not we have a failure.
    /// </summary>
    /// <param name="pipelineMethod">The method to invoke.</param>
    /// <param name="loggingInfo">Optional information about the functionality we are invoking.</param>
    /// <returns>True if the method was invoked successfully, false otherwise.</returns>
    internal static bool StaticInvoke(Func<pxcmStatus> pipelineMethod, [CallerMemberName]string loggingInfo = "")
    {
      Debug.WriteLine("Entering " + loggingInfo);

      try
      {
        pxcmStatus status = pipelineMethod();

        return status >= pxcmStatus.PXCM_STATUS_NO_ERROR;
      }
      finally
      {
        Debug.WriteLine("Finished " + loggingInfo);
      }
    }

    /// <summary>
    /// Invoke the method and determine whether or not we have a failure. 
    /// </summary>
    /// <param name="pipelineMethod">The method to invoke.</param>
    /// <param name="loggingInfo">Optional information about the functionality we are invoking.</param>
    /// <exception cref="InvalidStatusException">Thrown if the method failed.</exception>
    internal static void StaticInvokeAndThrow(Func<pxcmStatus> pipelineMethod, [CallerMemberName]string loggingInfo = "")
    {
      Debug.WriteLine("Entering " + loggingInfo);

      pxcmStatus status = pipelineMethod();
      if (status < pxcmStatus.PXCM_STATUS_NO_ERROR)
      {
        throw new InvalidStatusException("There was an issue inside " + loggingInfo, status);
      }

      Debug.WriteLine("Finished " + loggingInfo);
    }

    protected bool Invoke(Func<pxcmStatus> pipelineMethod, [CallerMemberName]string loggingInfo = "")
    {
      return StaticInvoke(pipelineMethod, loggingInfo);
    }

    protected void InvokeAndThrow(Func<pxcmStatus> pipelineMethod, [CallerMemberName]string loggingInfo = "")
    {
      StaticInvokeAndThrow(pipelineMethod, loggingInfo);
    }

    /// <summary>
    /// Dispose of resources.
    /// </summary>
    public void Dispose()
    {
      Dispose(true);
      GC.SuppressFinalize(this);
    }

    protected abstract void Dispose(bool disposing);

    /// <summary>
    /// Provides access to the sense manager functionality.
    /// </summary>
    internal ISenseManager SenseManager
    {
      get
      {
        if (senseManager == null)
        {
          senseManager = RuntimeAssert.IsNotNull(ServiceLocator.Instance.Get<ISenseManager>(), "ISenseManager");
        }
        return senseManager;
      }
    }
  }
}